package fr.upmc.i3s.upmcontact.views;

import com.jeremyfeinstein.slidingmenu.lib.SlidingMenu;
import com.jeremyfeinstein.slidingmenu.lib.SlidingMenu.OnOpenListener;

import fr.upmc.i3s.upmcontact.Constants;
import fr.upmc.i3s.upmcontact.R;
import fr.upmc.i3s.upmcontact.backend.BackEndBridge;
import fr.upmc.i3s.upmcontact.backend.BackEndBridgeImpl;
import fr.upmc.i3s.upmcontact.callbacks.ICollectAllCallback;
import fr.upmc.i3s.upmcontact.callbacks.IConnectivityChangeCallback;
import fr.upmc.i3s.upmcontact.content.collectors.CollectorsController;
import fr.upmc.i3s.upmcontact.content.containers.CollectedContentManager;
import fr.upmc.i3s.upmcontact.listeners.OnConnectionChangeListener;
import fr.upmc.i3s.upmcontact.tools.FileUtils;
import fr.upmc.i3s.upmcontact.tools.KeyboardUtils;
import fr.upmc.i3s.upmcontact.views.fragments.HomeFragment;
import fr.upmc.i3s.upmcontact.views.fragments.MenuFragment;
import fr.upmc.i3s.upmcontact.views.fragments.models.IFragmentModel;

import android.app.ActionBar;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.IntentFilter;
import android.content.DialogInterface.OnClickListener;
import android.content.Intent;
import android.net.ConnectivityManager;
import android.os.Bundle;
import android.os.Handler;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentTransaction;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup.LayoutParams;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.TextView;

import com.parse.Parse;
import com.parse.ParseAnalytics;

public class FragmentController extends FragmentBaseActivity implements IFragmentModel, Constants {
	
	private static volatile FragmentController INSTANCE = null;
	public static FragmentController getInstance() {
		return INSTANCE;
	}
	
	private Fragment mContent;
	private BackEndBridge backEndInstance;
	private Handler handler;
	
	private ProgressBar pbLoadingContent;
	private ImageView ivConnectivity;
	private SlidingMenu slidingMenu;
	
	private OnConnectionChangeListener connectivityListener;
	private boolean listenerRegistered;
	
	public FragmentController() {
		super(R.string.title_activity_home);
	}
	
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		INSTANCE = this;
		this.handler = new Handler();
		// init view
		setContentView(R.layout.activity_home);
		if (savedInstanceState != null) {
			mContent = getSupportFragmentManager().getFragment(savedInstanceState, "mContent");
		} if (mContent == null) {
			mContent = HomeFragment.getInstance();
		}
		// init application
		backEndInit();
		customizeActionBar();
		connectivityListener = new OnConnectionChangeListener(ivConnectivity, connectivityChangeCallback);
		initDirectories();
		// fetch and init views
		fetchViews();
		customizeViews();
		setListeners();
		// init content 
		if(!CollectorsController.getInstance(this).collectAtStartIfNeeded(this, collectAllCallback)) {
			CollectedContentManager.getInstance(this).loadAllSavedStates();
		}
	}
	
	@Override
	public void onPostCreate(Bundle savedInstanceState) {
	    super.onPostCreate(savedInstanceState);
	    this.handler.postDelayed(new Runnable() {
	        @Override
	        public void run() {
	            toggle();
	        }
	    }, 500);
	}
	
	@Override 
	public void onDestroy() {
		super.onDestroy();
		CollectedContentManager.getInstance(this).saveAllStates();
		if(listenerRegistered) {
			unregisterReceiver(connectivityListener);
			listenerRegistered = false;
		}
	}
	
	@Override
	public void onSaveInstanceState(Bundle outState) {
		super.onSaveInstanceState(outState);
	}
	
	@Override
	public void fetchViews() {
		this.slidingMenu = this.getSlidingMenu(); 
		this.pbLoadingContent = (ProgressBar) findViewById(R.id.progressBar_loading);
	}
	
	@Override
	public void customizeViews() {
		setSlidingMenuBehindContentView();
		getSlidingMenu().setTouchModeAbove(SlidingMenu.TOUCHMODE_FULLSCREEN);
		getSlidingMenu().setFadeEnabled(false);
		setSlidingActionBarEnabled(true);
		// set home fragment :
		switchContent(HomeFragment.getInstance());
	}
	
	@Override
	public void setListeners() {
		this.slidingMenu.setOnOpenListener(onOpenSlidingMenuListener);
		registerReceiver(connectivityListener, new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION));
		listenerRegistered = true;
	}
	
	@Override
	public void onActivityResult(int requestCode, int resultCode, Intent data) {
	   super.onActivityResult(requestCode, resultCode, data);
	}
	
	private void backEndInit() {
		Parse.initialize(this, BackEndBridgeImpl.APPLICATION_ID, BackEndBridgeImpl.CLIENT_KEY);
		ParseAnalytics.trackAppOpened(getIntent());
		this.backEndInstance = BackEndBridgeImpl.getInstance(this);
		this.backEndInstance.reinitBackEnd(this);
	}
	
	private void customizeActionBar() {
		LayoutInflater inflater = (LayoutInflater) getSystemService (Context.LAYOUT_INFLATER_SERVICE);
		View view = inflater.inflate(R.layout.layout_action_bar, null);
		getActionBar().setCustomView(view, new ActionBar.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
		getActionBar().setDisplayShowCustomEnabled(true);
		getActionBar().setDisplayShowHomeEnabled(false);
		getActionBar().setDisplayShowTitleEnabled(false);
		getActionBar().setDisplayUseLogoEnabled(false);
		TextView title = (TextView) findViewById(R.id.textView_title_activity);
		title.setText(getString(R.string.title_activity_home));
		ivConnectivity = (ImageView) findViewById(R.id.imageView_connectivity);
	}
	
	private void initDirectories() {
		FileUtils.createDirectory(APPLICATION_EXTERNAL_FOLDER);
		FileUtils.createDirectory(LOST_EXTERNAL_FOLDER);
		FileUtils.createDirectory(FOUND_EXTERNAL_FOLDER);
		FileUtils.createDirectory(INCIDENTS_EXTERNAL_FOLDER);
		FileUtils.createDirectory(UPMC_EXTERNAL_FOLDER);
		FileUtils.createDirectory(STUDENT_EXTERNAL_FOLDER);
		FileUtils.createDirectory(MERCHANTS_EXTERNAL_FOLDER);
	}
	
	  //////////////////
	 // SLIDING MENU //
	//////////////////
	
	public static final int TRANSACTION_NO_ANIM = 0;
	public static final int TRANSACTION_FROM_LEFT_TO_RIGHT = 1;
	public static final int TRANSACTION_FROM_RIGHT_TO_LEFT = 2;
	
	private void setSlidingMenuBehindContentView() {
		setBehindContentView(R.layout.menu_frame);
		getSupportFragmentManager()
		.beginTransaction()
		.replace(R.id.menu_frame, new MenuFragment())
		.commit();
	}
	
	public void switchContent(Fragment fragment) {
		switchContent(fragment, TRANSACTION_NO_ANIM);
	}
	
	public void switchContent(Fragment fragment, int transactionAnim) {
		getSlidingMenu().setTouchModeAbove(SlidingMenu.TOUCHMODE_FULLSCREEN);
		mContent = fragment;
		FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
		switch(transactionAnim) {
		case TRANSACTION_FROM_LEFT_TO_RIGHT:
			transaction.setCustomAnimations(R.anim.enter_from_left, R.anim.exit_to_right, R.anim.pop_enter_from_left, R.anim.pop_exit_to_right);
			break;
		case TRANSACTION_FROM_RIGHT_TO_LEFT:
			transaction.setCustomAnimations(R.anim.enter_from_right, R.anim.exit_to_left, R.anim.pop_enter_from_right, R.anim.pop_exit_to_left);
			break;
		case TRANSACTION_NO_ANIM:
		default:
			break;
		}
		transaction.replace(R.id.activity_home, fragment);
		transaction.commit();
		getSlidingMenu().showContent();
	}
	
	private OnOpenListener onOpenSlidingMenuListener = new OnOpenListener() {
		@Override
		public void onOpen() {
			KeyboardUtils.hideKeyboard(FragmentController.this);
		}
	};
	
	
	  ///////////////
	 // CALLBACKS //
	///////////////
	
	@Override
	public void onBackPressed() {
	    new AlertDialog.Builder(this)
	        .setTitle(R.string.really_exit)
	        .setMessage(R.string.really_exit_msg)
	        .setNegativeButton(android.R.string.no, null)
	        .setPositiveButton(android.R.string.yes, new OnClickListener() {
	            public void onClick(DialogInterface arg0, int arg1) {
	                FragmentController.super.onBackPressed();
	            }
	        }).create().show();
	}
	
	private IConnectivityChangeCallback connectivityChangeCallback = new  IConnectivityChangeCallback() {
		@Override
		public void changed(boolean connected, int type) {
			if(BackEndBridgeImpl.getInstance(FragmentController.this) == null) {
				BackEndBridgeImpl.getInstance(FragmentController.this).signin(null);
			}
		}
	};
	
	private ICollectAllCallback collectAllCallback = new ICollectAllCallback() {
		@Override
		public void collectEnded() {
			if(mContent instanceof HomeFragment) {
				HomeFragment.getInstance().updateRecentContent();
			}
		}
	};
	
	
	  /////////////
	 // CALLERS //
	/////////////
	
	public void setLoadingOn() {
		this.pbLoadingContent.setVisibility(View.VISIBLE);
	}
	
	public void setLoadingOff() {
		this.pbLoadingContent.setVisibility(View.GONE);
	}
	
}
